package com.jyniubi.core.config;


import com.jyniubi.core.config.redis.PrefixStringRedisSerializer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.data.redis.support.collections.RedisCollectionFactoryBean;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.time.Duration;

/**
 * redis 配置 键和值的序列化   缓存管理
 * @author jyzhang
 */
@Configuration
@Slf4j
public class RedisConfig {
    @Resource
    private RedisTemplate redisTemplate;
    /**
     * 缓存前缀：目前没用
     * todo：改为全局的前缀
     */
    @Value("${spring.redis.key-prefix}")
    private String redisKeyPrefix;
    /**
     * 缓存过期时间
     */
    @Value("${spring.redis.cache-expire}")
    private Integer redisCacheExpire;
    /**
     * //jdk自带的注解，标注的方法可以在构造器调用后立即执行
     */
    @PostConstruct
    public void init(){
//        PrefixStringRedisSerializer prefixStringRedisSerializer = new PrefixStringRedisSerializer(redisKeyPrefix);
//        redisTemplate.setKeySerializer(prefixStringRedisSerializer); //键转为字符串
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());//值转为json字符串
    }
    @Bean
    public CacheManager cacheManager(LettuceConnectionFactory lettuceConnectionFactory){
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(redisCacheExpire))
//                .computePrefixWith(cacheName -> redisKeyPrefix + cacheName + ":")
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
                /*.disableCachingNullValues()*/;//注掉不缓存空值，防止内存穿透，缓存空值的话下次空值查询就不用走redis查询不到再走数据库了
        log.info("cacheManager加载完成...");
        return RedisCacheManager.builder(lettuceConnectionFactory)
                .cacheDefaults(redisCacheConfiguration)
                .transactionAware() //事务
                .build();
    }
}
